﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ChildPhotosManager.Core.Dtos;
using ChildPhotosManager.Core.Entities;
using ChildPhotosManager.Core.Services;
using ChildPhotosManager.Data;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;

namespace ChildPhotosManager.Web.Services;

public class PhotoService : IPhotoService
{
    private readonly AppDbContext _context;
    private readonly IWebHostEnvironment _webHostEnv;
    private readonly IConfiguration _configuration;

    // 构造函数注入依赖
    public PhotoService(AppDbContext context, IWebHostEnvironment webHostEnv, IConfiguration configuration)
    {
        _context = context;
        _webHostEnv = webHostEnv;
        _configuration = configuration;
    }

    /// <summary>
    /// 上传照片并保存到服务器和数据库
    /// </summary>
    public async Task<Photo> UploadPhotoAsync(IFormFile file, string? description, string? category)
    {
        // 验证文件
        if (file == null || file.Length == 0)
            throw new ArgumentException("请选择有效的图片文件");

        // 验证文件类型（只允许图片）
        var allowedContentTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/webp" };
        if (!allowedContentTypes.Contains(file.ContentType))
            throw new ArgumentException("只支持JPG、PNG、GIF、WebP格式的图片");

        // 验证文件大小（最大5MB）
        if (file.Length > 5 * 1024 * 1024)
            throw new ArgumentException("图片大小不能超过5MB");

        // 准备存储路径（wwwroot/uploads）
        var photoRootPath = GetPhotoRootPath();
        var uploadsFolder = Path.Combine(photoRootPath, "uploads");
        if(!Directory.Exists(uploadsFolder))
            Directory.CreateDirectory(uploadsFolder); // 确保文件夹存在

        // 生成唯一文件名（避免重名）
        var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
        var filePath = Path.Combine(uploadsFolder, fileName);

        // 保存文件到服务器
        await using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        var relativePath = Path.Combine("uploads", fileName); // 相对路径（用于数据库存储）

        // 创建Photo实体并保存到数据库
        var photo = new Photo
        {
            FileName = file.FileName,
            StoredFileName = relativePath,
            ContentType = file.ContentType,
            FileSize = file.Length,
            UploadTime = DateTime.Now,
            Description = description,
            Category = category
        };

        _context.Photos.Add(photo);
        await _context.SaveChangesAsync();

        return photo;
    }

    /// <summary>
    /// 根据ID获取照片
    /// </summary>
    public async Task<Photo?> GetPhotoByIdAsync(int id)
    {
        return await _context.Photos.FindAsync(id);
    }

    /// <summary>
    /// 获取所有照片（支持按分类筛选）
    /// </summary>
    public async Task<IEnumerable<PhotoViewModel>> GetAllPhotosAsync(string? category = null)
    {
        var query = _context.Photos.AsQueryable();

        // 筛选分类
        if (!string.IsNullOrEmpty(category))
        {
            query = query.Where(p => p.Category == category);
        }

        // 转换为ViewModel并排序（最新的在前面）
        return await query
            .OrderByDescending(p => p.UploadTime)
            .Select(p => new PhotoViewModel
            {
                Id = p.Id,
                FileName = p.FileName,
                StoredFileName = p.StoredFileName,
                ContentType = p.ContentType,
                FileSize = p.FileSize,
                UploadTime = p.UploadTime,
                Description = p.Description,
                Category = p.Category
            })
            .ToListAsync();
    }

    /// <summary>
    /// 获取所有分类（去重）
    /// </summary>
    public async Task<IEnumerable<string>> GetAllCategoriesAsync()
    {
        return await _context.Photos
            .Where(p => !string.IsNullOrEmpty(p.Category))
            .Select(p => p.Category!)
            .Distinct()
            .OrderBy(c => c)
            .ToListAsync();
    }

    public async Task<Photo> UpdatePhotoAsync(int id, string? description, string? category)
    {
         var photo = await _context.Photos.FindAsync(id);
        if (photo == null)
            throw new KeyNotFoundException("照片不存在");

        // 更新描述和分类
        photo.Description = description;
        photo.Category = category;
        await _context.SaveChangesAsync();
        return photo;
    }

    public async Task DeletePhotoAsync(int id)
    {
        var photo = await _context.Photos.FindAsync(id);
        if (photo == null)
            return;

        // 1.删除服务器上的图片文件
        var photoRootPath = GetPhotoRootPath();
        var fullPath = Path.Combine(photoRootPath, photo.StoredFileName);
        if (File.Exists(fullPath))
            File.Delete(fullPath);

        // 2.删除数据库中的记录
        _context.Photos.Remove(photo);
        await _context.SaveChangesAsync();
    }

    public async Task<PagedResult<PhotoViewModel>> GetPhotosByPageAsync(int pageNumber = 1, 
                                                int pageSize = 4, string? category = null)
    {
        // 验证页码（避免负数或0）
        pageNumber = Math.Max(pageNumber, 1);

        // 构建查询（带分类筛选）
        var query = _context.Photos.AsQueryable();
        if (!string.IsNullOrEmpty(category))
        {
            query = query.Where(p => p.Category == category);
        }

        // 计算总记录数
        var totalItems = await query.CountAsync();

        // 分页查询当前页数据（Skip跳过前面的记录，Take获取当前页记录）
        var items = await query
            .OrderByDescending(p => p.UploadTime)
            .Skip((pageNumber - 1) * pageSize)
            .Take(pageSize)
            .Select(p => new PhotoViewModel
            {
                Id = p.Id,
                FileName = p.FileName,
                StoredFileName = p.StoredFileName,
                ContentType = p.ContentType,
                FileSize = p.FileSize,
                UploadTime = p.UploadTime,
                Description = p.Description,
                Category = p.Category
            })
            .ToListAsync();

        // 返回分页结果
        return new PagedResult<PhotoViewModel>
        {
            Items = items,
            CurrentPage = pageNumber,
            PageSize = pageSize,
            TotalItems = totalItems
        };
    }

    private string GetPhotoRootPath()
    {
        return _configuration["FileStorage:PhotoRootPath"] ?? Path.Combine(_webHostEnv.ContentRootPath, "wwwroot", "uploads");
    }
}